home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / sat / msat09.tgz / DIRECTOR.C < prev    next >
Text File  |  1994-09-17  |  18KB  |  688 lines

  1. /*
  2.  *   Copyright 1992, 1993, 1994 John Melton (G0ORX/N6LYT)
  3.  *              All Rights Reserved
  4.  *
  5.  *   This program is free software; you can redistribute it and/or modify
  6.  *   it under the terms of the GNU General Public License as published by
  7.  *   the Free Software Foundation; either version 1, or (at your option)
  8.  *   any later version.
  9.  *
  10.  *   This program is distributed in the hope that it will be useful,
  11.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *   GNU General Public License for more details.
  14.  *
  15.  *   You should have received a copy of the GNU General Public License
  16.  *   along with this program; if not, write to the Free Software
  17.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  */
  20.  
  21. /*
  22.     directory.c
  23.  
  24.     list pacsat directory
  25.  
  26.     John Melton
  27.     G0ORX, N6LYT
  28.  
  29.     4 Charlwoods Close
  30.     Copthorne
  31.     West Sussex
  32.     RH10 3QZ
  33.     England
  34.  
  35.     INTERNET:    g0orx@amsat.org
  36.             n6lyt@amsat.org
  37.             john@images.demon.co.uk
  38.             J.D.Melton@slh0613.icl.wins.co.uk
  39.  
  40.     History:
  41.  
  42.     0.1    Initial version.            G0ORX
  43.     0.2    Added view selection.            G0ORX
  44.     0.3    Fixed selected entry after update.    G0ORX
  45.     0.4    Added Fill button.            G0ORX
  46.     0.5    Free file buffer.            G0ORX
  47.     0.6    Converted to Xaw.            G4KLX
  48.     0.7    Added double click for filling.        G4KLX
  49.         Changed request format + cancel.
  50.         Added "Logs" to view selection.
  51.     0.8    Read pb__nnnn.pfh in reverse order.    G4KLX
  52.         Added Order button.
  53. */
  54.  
  55. #define VERSION_STRING "(version 0.8 by g0orx/n6lyt/g4klx)"
  56.  
  57. #include <stdio.h>
  58. #include <stdlib.h>
  59. #include <unistd.h>
  60. #include <sys/types.h>
  61. #include <netinet/in.h>
  62. #include <fcntl.h>
  63. #include <dirent.h>
  64. #include <ctype.h>
  65. #include <time.h>
  66.  
  67. #include <X11/Intrinsic.h>
  68. #include <X11/StringDefs.h>
  69. #include <X11/Shell.h>
  70. #include <X11/Xaw/Cardinals.h>
  71. #include <X11/Xaw/Form.h>
  72. #include <X11/Xaw/Label.h>
  73. #include <X11/Xaw/List.h>
  74. #include <X11/Xaw/Command.h>
  75. #include <X11/Xaw/MenuButton.h>
  76. #include <X11/Xaw/Viewport.h>
  77.  
  78. #include "xawutils.h"
  79. #include "header.h"
  80. #include "request.h"
  81. #include "ftl0.h"
  82.  
  83. Display *dpy;
  84. int scrn;
  85.  
  86. XtAppContext app_context;
  87.  
  88. typedef struct
  89. {
  90.     XFontStruct *bold_font, *button_font, *menu_font, *label_font, *list_font;
  91. }
  92. Resources;
  93.  
  94. Resources  resources;
  95.  
  96. Widget toplevel, compwindow, quitbutton, updatebutton, cancelbutton,
  97.     filldirbutton, viewtypebutton, viewtypelabel, orderlabel, orderbutton,
  98.     listlabel, viewport, dirlist;
  99.  
  100. static XtResource resource_list[] =
  101. {
  102.     {"boldFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  103.         XtOffsetOf(Resources, bold_font), XtRString, XtDefaultFont},
  104.     {"buttonFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  105.         XtOffsetOf(Resources, button_font), XtRString, XtDefaultFont},
  106.     {"menuFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  107.         XtOffsetOf(Resources, menu_font), XtRString, XtDefaultFont},
  108.     {"labelFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  109.         XtOffsetOf(Resources, label_font), XtRString, XtDefaultFont},
  110.     {"listFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
  111.         XtOffsetOf(Resources, list_font), XtRString, XtDefaultFont}
  112. };
  113.  
  114. static Arg shell_args[] =
  115. {
  116.     {XtNtitle,        (XtArgVal)NULL}
  117. };
  118.  
  119. static Arg form_args[] =
  120. {
  121.     {XtNdefaultDistance,    (XtArgVal)0}
  122. };
  123.  
  124. static Arg label_args[] =
  125. {
  126.     {XtNfromVert,        (XtArgVal)NULL},
  127.     {XtNfromHoriz,        (XtArgVal)NULL},
  128.     {XtNlabel,        (XtArgVal)NULL},
  129.     {XtNwidth,        (XtArgVal)0},
  130.     {XtNfont,        (XtArgVal)NULL},
  131.     {XtNborderWidth,    (XtArgVal)0},
  132.     {XtNresize,        False},
  133.     {XtNjustify,        XtJustifyLeft},
  134.     {XtNvertDistance,    (XtArgVal)6},
  135.     {XtNhorizDistance,    (XtArgVal)8},
  136.     {XtNtop,        XtChainTop},
  137.     {XtNbottom,        XtChainTop},
  138.     {XtNleft,        XtChainLeft},
  139.     {XtNright,        XtChainLeft}
  140. };
  141.  
  142. static Arg button_args[] =
  143. {
  144.     {XtNcallback,        (XtArgVal)NULL},
  145.     {XtNlabel,        (XtArgVal)NULL},
  146.     {XtNfont,        (XtArgVal)NULL},
  147.     {XtNfromHoriz,        (XtArgVal)NULL},
  148.     {XtNfromVert,        (XtArgVal)NULL},
  149.     {XtNvertDistance,    (XtArgVal)6},
  150.     {XtNhorizDistance,    (XtArgVal)8},
  151.     {XtNresize,        False},
  152.     {XtNtop,        XtChainTop},
  153.     {XtNbottom,        XtChainTop},
  154.     {XtNleft,        XtChainLeft},
  155.     {XtNright,        XtChainLeft}
  156. };
  157.  
  158. static Arg menu_button_args[] =
  159. {
  160.     {XtNlabel,        (XtArgVal)NULL},
  161.     {XtNfont,        (XtArgVal)NULL},
  162.     {XtNfromHoriz,        (XtArgVal)NULL},
  163.     {XtNwidth,        (XtArgVal)80},
  164.     {XtNresize,        False},
  165.     {XtNvertDistance,    (XtArgVal)6},
  166.     {XtNhorizDistance,    (XtArgVal)8},
  167.     {XtNtop,        XtChainTop},
  168.     {XtNbottom,        XtChainTop},
  169.     {XtNleft,        XtChainLeft},
  170.     {XtNright,        XtChainLeft},
  171.     {XtNjustify,        XtJustifyCenter}
  172. };
  173.  
  174. static Arg viewport_args[] =
  175. {
  176.     {XtNfromVert,        (XtArgVal)NULL},
  177.     {XtNwidth,        (XtArgVal)600},
  178.     {XtNheight,        (XtArgVal)150},
  179.     {XtNforceBars,        True},
  180.     {XtNallowVert,        True},
  181.     {XtNresize,        True},
  182.     {XtNvertDistance,    (XtArgVal)0},
  183.     {XtNhorizDistance,    (XtArgVal)0},
  184.     {XtNtop,        XtChainTop},
  185.     {XtNbottom,        XtChainBottom},
  186.     {XtNleft,        XtChainLeft},
  187.     {XtNright,        XtChainRight}
  188. };
  189.  
  190. static Arg list_args[] =
  191. {
  192.     {XtNcallback,        (XtArgVal)NULL},
  193.     {XtNfont,        (XtArgVal)NULL}
  194. };
  195.  
  196. MenuEntry type_menu[] =
  197. {
  198.     {"All",            "type1",    0},
  199.     {"My Mail",        "type2",    1},
  200.     {"Broadcast",        "type3",    2},
  201.     {"Logs",        "type4",    3},
  202.     {"EIS",            "type5",    4}
  203. };
  204.  
  205. MenuEntry order_menu[] =
  206. {
  207.     {"Date/Time",        "order1",    0},
  208.     {"Id",            "order2",    1},
  209.     {"From",        "order3",    2},
  210.     {"To",            "order4",    3},
  211.     {"Size",        "order5",    4},
  212.     {"Title",        "order6",    5}
  213. };
  214.  
  215. #define    MAX_DIR_FILE_SIZE    40
  216. #define    MAX_DIR_LIST_SIZE    2000
  217.  
  218. char myCall[16];
  219. char satelliteId[16];
  220.  
  221. String dList[MAX_DIR_LIST_SIZE + 1];
  222. int    nList = 0;
  223.  
  224. char *dDir[MAX_DIR_FILE_SIZE];
  225. int  nDir = 0;
  226.  
  227. int lastIndex = 0;
  228.  
  229. int view  = 0;
  230. int order = 0;
  231.  
  232. int sock;
  233. struct sockaddr_in loc_addr;
  234. struct sockaddr_in rem_addr;
  235.  
  236. void LoadDirectory(char *dirName);
  237.  
  238. int dircomp(const void *first, const void *second)
  239. {
  240.     char **a = (char **)first;
  241.     char **b = (char **)second;
  242.     int n;
  243.  
  244.     switch (order)
  245.     {
  246.         case 0: /* Date/Time */
  247.             break;
  248.         case 1: /* Id */
  249.             if ((n = strncmp(*b, *a, 8)) != 0)
  250.                 return(n);
  251.             break;
  252.         case 2: /* From */
  253.             if ((n = strncasecmp(*b + 19, *a + 19, 8)) != 0)
  254.                 return(n);
  255.             break;
  256.         case 3: /* To */
  257.             if ((n = strncasecmp(*b + 28, *a + 28, 8)) != 0)
  258.                 return(n);
  259.             break;
  260.         case 4: /* Size */
  261.             if ((n = strncmp(*b + 37, *a + 37, 6)) != 0)
  262.                 return(n);
  263.             break;
  264.         case 5: /* Title */
  265.             if ((n = strncasecmp(*b + 44, *a + 44, 40)) != 0)
  266.                 return(n);
  267.             break;
  268.     }
  269.  
  270.     return(strncmp(*b + 9, *a + 9, 9));
  271. }
  272.  
  273. int namecomp(const void *first, const void *second)
  274. {
  275.     char **a = (char **)first;
  276.     char **b = (char **)second;
  277.  
  278.     return(strcmp(*b, *a));
  279. }
  280.  
  281. void Update(void)
  282. {
  283.     struct dirent *pDirent;
  284.     Arg args[2];
  285.     DIR *pDir;
  286.     int i;
  287.  
  288.     nDir = 0;
  289.  
  290.     /* walk through the directory files */
  291.     pDir = opendir(".");
  292.  
  293.     while ((pDirent = readdir(pDir)) != NULL && nDir < MAX_DIR_FILE_SIZE)
  294.         if (strncmp(pDirent->d_name, "pb__", 4) == 0)
  295.             dDir[nDir++] = XtNewString(pDirent->d_name);
  296.  
  297.     closedir(pDir);
  298.  
  299.     qsort(dDir, nDir, sizeof(char *), namecomp);
  300.  
  301.     for (i = 0; i < nList; i++) XtFree(dList[i]);
  302.  
  303.     nList     = 0;
  304.     lastIndex = -1;
  305.  
  306.     for (i = 0; nList < MAX_DIR_LIST_SIZE && i < nDir; i++)
  307.         LoadDirectory(dDir[i]);
  308.  
  309.     for (i = 0; i < nDir; i++) XtFree(dDir[i]);
  310.  
  311.     qsort(dList, nList, sizeof(String), dircomp);
  312.  
  313.     dList[nList] = NULL;
  314.  
  315.     XawListChange(dirlist, dList, nList, 0, False);
  316.  
  317.     if (nList > 0) XawListHighlight(dirlist, 0);
  318.  
  319.     XtSetArg(args[0], XtNheight, 0);
  320.     XtSetArg(args[1], XtNwidth,  0);
  321.     XtSetValues(dirlist, args, TWO);
  322. }
  323.  
  324. void DirTypeCb(Widget w, XtPointer client_data, XtPointer call_data)
  325. {
  326.     view = (int)client_data;
  327.  
  328.     XtVaSetValues(viewtypebutton, XtNlabel, type_menu[view].Label, NULL);
  329.  
  330.     Update();
  331. }
  332.  
  333. void OrderCb(Widget w, XtPointer client_data, XtPointer call_data)
  334. {
  335.     order = (int)client_data;
  336.  
  337.     XtVaSetValues(orderbutton, XtNlabel, order_menu[order].Label, NULL);
  338.  
  339.     qsort(dList, nList, sizeof(String), dircomp);
  340.  
  341.     XawListChange(dirlist, dList, nList, 0, False);
  342.  
  343.     if (nList > 0) XawListHighlight(dirlist, 0);
  344. }
  345.  
  346. void UpdateCb(Widget w, XtPointer client_data, XtPointer call_data)
  347. {
  348.     Update();
  349. }
  350.  
  351. void QuitCb(Widget w, XtPointer client_data, XtPointer call_data)
  352. {
  353.     XtDestroyApplicationContext(app_context);
  354.     
  355.     exit(0);
  356. }
  357.  
  358. void LoadDirectory(char * dirName)
  359. {
  360.     FILE *hDir;
  361.     int fileLength;
  362.     int offset;
  363.     char *pBuffer, *source, *destination;
  364.     static struct tm * GMT;
  365.     char szTemp[128];
  366.     int headerSize;
  367.     HEADER *pHeader;
  368.     int j;
  369.     int display;
  370.     char *p;
  371.  
  372.     /* open the directory file */
  373.     if ((hDir = fopen(dirName, "r")) == NULL)
  374.     {
  375.         sprintf(szTemp, "Cannot open file %s", dirName);
  376.         MessageBox(szTemp);
  377.         return;
  378.     }
  379.  
  380.     /* get the file length */
  381.     fseek(hDir, 0L, SEEK_END);
  382.  
  383.     fileLength = ftell(hDir);
  384.  
  385.     pBuffer = XtMalloc(fileLength);
  386.  
  387.     fseek(hDir, 0L, SEEK_SET);
  388.  
  389.     /* read in the complete file */
  390.     fread(pBuffer, 1, fileLength, hDir);
  391.  
  392.     /* close the file */
  393.     fclose(hDir);
  394.  
  395.     /* walk through the file extracting the headers */
  396.     offset = 0;
  397.  
  398.     while (offset < fileLength)
  399.     {
  400.         if ((pHeader = ExtractHeader(pBuffer + offset, fileLength - offset, &headerSize)) == NULL)
  401.         {
  402.             MessageBox("Invalid header entry");
  403.             offset = fileLength;
  404.         }
  405.         else
  406.         {
  407.             source      = XtNewString(pHeader->source);
  408.             destination = XtNewString(pHeader->destination);
  409.         
  410.             /* truncate the source and destination */
  411.             j = 0;
  412.             while (isalnum(pHeader->source[j]) != '\0') j++;
  413.                   pHeader->source[j] = '\0';
  414.  
  415.             j = 0;
  416.             while (isalnum(pHeader->destination[j]) != '\0') j++;
  417.                   pHeader->destination[j] = '\0';
  418.  
  419.             GMT = gmtime(&pHeader->uploadTime);
  420.  
  421.             if (strlen(pHeader->title) == 0)
  422.                 sprintf(szTemp, "%8lx %02d%02d/%02d%02d %-8s %-8s %6ld %-40s",
  423.                     pHeader->fileId,
  424.                     GMT->tm_mon + 1, GMT->tm_mday, GMT->tm_hour, GMT->tm_min,
  425.                     pHeader->source,
  426.                     pHeader->destination,
  427.                     pHeader->fileSize,
  428.                     pHeader->fileName);
  429.             else
  430.                 sprintf(szTemp, "%8lx %02d%02d/%02d%02d %-8s %-8s %6ld %-40s",
  431.                     pHeader->fileId,
  432.                     GMT->tm_mon + 1, GMT->tm_mday, GMT->tm_hour, GMT->tm_min,
  433.                     pHeader->source,
  434.                     pHeader->destination,
  435.                     pHeader->fileSize,
  436.                     pHeader->title);
  437.  
  438.             if (headerSize > pHeader->bodyOffset)
  439.                 offset += headerSize;
  440.             else
  441.                 offset += pHeader->bodyOffset;
  442.  
  443.             for (p = source; *p != '\0'; p++)
  444.                 if (islower(*p)) *p=toupper(*p);
  445.  
  446.             for (p = destination; *p != '\0'; p++)
  447.                 if (islower(*p)) *p=toupper(*p);
  448.  
  449.             display = FALSE;
  450.  
  451.             switch (view)
  452.             {
  453.                 case 0:
  454.                     display = TRUE;
  455.                     break;
  456.                 case 1:
  457.                     if (strstr(source, myCall)      != NULL ||
  458.                         strstr(destination, myCall) != NULL)
  459.                         display = TRUE;
  460.                     break;
  461.                 case 2:
  462.                     if (strstr(destination, "ALL") != NULL)
  463.                         display = TRUE;
  464.                     break;
  465.                 case 3:
  466.                     if (pHeader->fileType >= 100  &&
  467.                         pHeader->fileType != 221)
  468.                              display = TRUE;
  469.                     break;
  470.                 case 4:
  471.                     if (pHeader->fileType == 220 ||
  472.                         pHeader->fileType == 221)
  473.                         display = TRUE;
  474.                     break;
  475.                 default:
  476.                     break;
  477.             }
  478.  
  479.             if (display)
  480.             {
  481.                 dList[nList] = XtNewString(szTemp);
  482.                 nList++;
  483.             }
  484.  
  485.             XtFree((char *)pHeader);
  486.             XtFree(source);
  487.             XtFree(destination);
  488.         }
  489.     }
  490.  
  491.     XtFree(pBuffer);
  492. }
  493.  
  494. void CancelFillCb(Widget w, XtPointer client_data, XtPointer call_data)
  495. {
  496.     struct request request;
  497.  
  498.  
  499.     request.type   = REQ_TYPE_CANCEL;
  500.     request.fileId = 0L;
  501.  
  502.     if (sendto(sock, (char *)&request, sizeof(struct request), 0, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) == -1)
  503.         MessageBox("xpb is not listening");
  504. }
  505.  
  506. void SelectCb(Widget w, XtPointer client_data, XtPointer call_data)
  507. {
  508.     XawListReturnStruct *selected;
  509.     struct request request;
  510.  
  511.     selected = (XawListReturnStruct *)call_data;
  512.  
  513.     if (selected->list_index != lastIndex)
  514.     {
  515.         lastIndex = selected->list_index;
  516.         return;
  517.     }
  518.  
  519.     lastIndex = -1;
  520.  
  521.     request.type = REQ_TYPE_FILE;
  522.     sscanf(selected->string, "%lx", &request.fileId);
  523.  
  524.     if (sendto(sock, (char *)&request, sizeof(struct request), 0, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) == -1)
  525.         MessageBox("xpb is not listening");
  526. }
  527.  
  528. void FillDirCb(Widget w, XtPointer client_data, XtPointer call_data)
  529. {
  530.     struct request request;
  531.  
  532.     request.type   = REQ_TYPE_DIR;
  533.     request.fileId = 0L;
  534.  
  535.     if (sendto(sock, (char *)&request, sizeof(struct request), 0, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) == -1)
  536.         MessageBox("xpb is not listening");
  537. }
  538.  
  539. int main(int argc, char **argv)
  540. {
  541.     static XtCallbackRec callback[2];
  542.     char title[80], *s;
  543.  
  544.     if ((s = getenv("MYCALL")) == NULL)
  545.         strcpy(myCall, "NOCALL");
  546.     else
  547.         strcpy(myCall, s);
  548.  
  549.     if ((s = getenv("SATELLITE")) == NULL)
  550.     {
  551.         printf("SATELLITE environment variable not set.\n");
  552.         return(1);
  553.     }
  554.  
  555.     strcpy(satelliteId , s);
  556.  
  557.     toplevel = XtAppInitialize(&app_context, "Xpb", NULL, 0, &argc, argv,
  558.                 NULL, shell_args, XtNumber(shell_args));
  559.  
  560.     sprintf(title, "directory:%s %s", satelliteId, VERSION_STRING);
  561.     XtVaSetValues(toplevel, XtNtitle, title, NULL);
  562.  
  563.     dpy  = XtDisplay(toplevel);
  564.     scrn = DefaultScreen(dpy);
  565.  
  566.     XtGetApplicationResources(toplevel, &resources,
  567.                 resource_list, XtNumber(resource_list),
  568.                 NULL, ZERO);
  569.  
  570.     compwindow = XtCreateManagedWidget("appForm", formWidgetClass,
  571.                 toplevel, form_args, XtNumber(form_args));
  572.  
  573.     callback[0].callback = QuitCb;
  574.     callback[0].closure  = toplevel;
  575.     button_args[0].value = (XtArgVal)callback;
  576.     button_args[1].value = (XtArgVal)"Quit";
  577.     button_args[2].value = (XtArgVal)resources.button_font;
  578.     quitbutton = XtCreateManagedWidget("quitButton", commandWidgetClass,
  579.                 compwindow, button_args, XtNumber(button_args));
  580.  
  581.     callback[0].callback = UpdateCb;
  582.     callback[0].closure  = toplevel;
  583.     button_args[0].value = (XtArgVal)callback;
  584.     button_args[1].value = (XtArgVal)"Update";
  585.     button_args[3].value = (XtArgVal)quitbutton;
  586.     updatebutton = XtCreateManagedWidget("updateButton", commandWidgetClass,
  587.                 compwindow, button_args, XtNumber(button_args));
  588.  
  589.     callback[0].callback = CancelFillCb;
  590.     callback[0].closure  = toplevel;
  591.     button_args[0].value = (XtArgVal)callback;
  592.     button_args[1].value = (XtArgVal)"Cancel Fill";
  593.     button_args[3].value = (XtArgVal)updatebutton;
  594.     cancelbutton = XtCreateManagedWidget("cancelButton", commandWidgetClass,
  595.                 compwindow, button_args, XtNumber(button_args));
  596.  
  597.     callback[0].callback = FillDirCb;
  598.     callback[0].closure  = toplevel;
  599.     button_args[0].value = (XtArgVal)callback;
  600.     button_args[1].value = (XtArgVal)"Fill Directory";
  601.     button_args[3].value = (XtArgVal)cancelbutton;
  602.     filldirbutton = XtCreateManagedWidget("dirButton", commandWidgetClass,
  603.                 compwindow, button_args, XtNumber(button_args));
  604.  
  605.     label_args[0].value = (XtArgVal)NULL;
  606.     label_args[1].value = (XtArgVal)filldirbutton;
  607.     label_args[2].value = (XtArgVal)"View";
  608.     label_args[4].value = (XtArgVal)resources.label_font;
  609.     viewtypelabel = XtCreateManagedWidget("viewtypeLabel", labelWidgetClass,
  610.                 compwindow, label_args, XtNumber(label_args));
  611.  
  612.     menu_button_args[0].value = (XtArgVal)type_menu[0].Label;
  613.     menu_button_args[1].value = (XtArgVal)resources.button_font;
  614.     menu_button_args[2].value = (XtArgVal)viewtypelabel;
  615.     viewtypebutton = XtCreateManagedWidget("viewtypeButton", menuButtonWidgetClass,
  616.                 compwindow, menu_button_args, XtNumber(menu_button_args));
  617.  
  618.     createMenuPopup(viewtypebutton, resources.menu_font, type_menu,
  619.                 XtNumber(type_menu), DirTypeCb);
  620.  
  621.     label_args[0].value = (XtArgVal)NULL;
  622.     label_args[1].value = (XtArgVal)viewtypebutton;
  623.     label_args[2].value = (XtArgVal)"Order";
  624.     label_args[4].value = (XtArgVal)resources.label_font;
  625.     orderlabel = XtCreateManagedWidget("orderLabel", labelWidgetClass,
  626.                 compwindow, label_args, XtNumber(label_args));
  627.  
  628.     menu_button_args[0].value = (XtArgVal)order_menu[0].Label;
  629.     menu_button_args[1].value = (XtArgVal)resources.button_font;
  630.     menu_button_args[2].value = (XtArgVal)orderlabel;
  631.     orderbutton = XtCreateManagedWidget("orderButton", menuButtonWidgetClass,
  632.                 compwindow, menu_button_args, XtNumber(menu_button_args));
  633.  
  634.     createMenuPopup(orderbutton, resources.menu_font, order_menu,
  635.                 XtNumber(order_menu), OrderCb);
  636.  
  637.     label_args[0].value = (XtArgVal)quitbutton;
  638.     label_args[1].value = (XtArgVal)NULL;
  639.     label_args[2].value = (XtArgVal)"       Id Date/Time From     To         Size Title";
  640.     label_args[3].value = (XtArgVal)500;
  641.     label_args[4].value = (XtArgVal)resources.list_font;
  642.     listlabel = XtCreateManagedWidget("listLabel", labelWidgetClass,
  643.                 compwindow, label_args, XtNumber(label_args));
  644.  
  645.     viewport_args[0].value = (XtArgVal)listlabel;
  646.     viewport = XtCreateManagedWidget("directoryViewport", viewportWidgetClass,
  647.                 compwindow, viewport_args, XtNumber(viewport_args));
  648.         
  649.     callback[0].callback = SelectCb;
  650.     callback[0].closure  = toplevel;
  651.     list_args[0].value = (XtArgVal)callback;
  652.     list_args[1].value = (XtArgVal)resources.list_font;
  653.     dirlist = XtCreateManagedWidget("directoryList", listWidgetClass,
  654.                 viewport, list_args, XtNumber(list_args));
  655.  
  656.     createMessagePopup(resources.bold_font, resources.button_font);
  657.  
  658.     /* setup to talk to xpb */
  659.     memset((char *)&loc_addr, 0, sizeof(rem_addr));
  660.     loc_addr.sin_family      = AF_INET;
  661.     loc_addr.sin_addr.s_addr = INADDR_ANY;
  662.     loc_addr.sin_port        = htons(0);
  663.  
  664.     if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
  665.     {
  666.         perror("socket");
  667.     }
  668.  
  669.     if (bind(sock, (struct sockaddr *)&loc_addr, sizeof(loc_addr)) == -1)
  670.     {
  671.         perror("bind");
  672.     }
  673.  
  674.     memset((char *)&rem_addr, 0, sizeof(rem_addr));
  675.     rem_addr.sin_family      = AF_INET;
  676.     rem_addr.sin_port        = htons(5100);
  677.     rem_addr.sin_addr.s_addr = htonl(0x7f000001);
  678.  
  679.     view = 0;
  680.     Update();
  681.  
  682.     XtRealizeWidget(toplevel);
  683.  
  684.     XtAppMainLoop(app_context);
  685.  
  686.     return(0);
  687. }
  688.